package de.alexhepp.widgets.messagewidget;

/**
 * Copyright (C) 2011 Alex Hepp
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the 
 * GNU General Public License as published by the Free Software Foundation; 
 * either version 3 of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program;
 * if not, see <http://www.gnu.org/licenses/>.
 */

import java.util.ArrayList;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;

/**
 * Define a simple widget that shows all SMS / all unread SMS. 
 * We observe the content provider for SMS and spawn a {@link Service} to perform the API queries and 
 * update the view.
 */
public class MessageWidget extends AppWidgetProvider {

	/** TAG used for Debug-Logging */
	public static final String LOG_TAG = "MessageWidget";
	
	public static final String SMS_CONTENT_OBSERVER = "content://mms-sms";

	private static int position=0;
	
	/**
	 * Actions fired by the widget to react to the buttons
	 */
	public static final String SHOW_NEXT_SMS_ACTION = "de.alexhepp.widgets.MessageWidget.SHOW_NEXT_SMS";
	public static final String SHOW_PREVIOUS_SMS_ACTION = "de.alexhepp.widgets.MessageWidget.SHOW_PREVIOUS_SMS";

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {

		SMSObserver observer = new SMSObserver(null);
		observer.setContext(context);
		context.getContentResolver().registerContentObserver(Uri.parse(SMS_CONTENT_OBSERVER), true, observer);
		
		Intent updateServiceIntent = new Intent(context, UpdateService.class);
		context.startService(updateServiceIntent);
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		try {
			String action = intent.getAction();
			if (action.equals(SHOW_NEXT_SMS_ACTION)) {
				++position;
//				Log.v(LOG_TAG, "Next SMS_ACTION");
				
				Intent updateServiceIntent = new Intent(context, UpdateService.class);
				context.startService(updateServiceIntent);
			} else if (action.equals(SHOW_PREVIOUS_SMS_ACTION)) {
				--position;
//				Log.v(LOG_TAG, "Previous SMS_ACTION");
				
				Intent updateServiceIntent = new Intent(context, UpdateService.class);
				context.startService(updateServiceIntent);
			} 
			else{
				// make sure, that also other callback handlers are called.
				super.onReceive(context, intent);
			}
		} catch (Throwable t) {
			// trying to catch everything that would cause the widget to crash
			Log.e(LOG_TAG, "reached catchall clause, something bad happened in MessageWidget#onReceive()");
			t.printStackTrace();
		}
		
	}
	
	public static class UpdateService extends Service {
		@Override
		public void onStart(Intent intent, int startId) {
			// Build the widget update for today
			RemoteViews newWidgetDisplay = displaySMS(this);

			// Push update for this widget to the home screen
			ComponentName thisWidget = new ComponentName(this, MessageWidget.class);
			AppWidgetManager manager = AppWidgetManager.getInstance(this);
			manager.updateAppWidget(thisWidget, newWidgetDisplay);
		}

		/**
		 * Now build the new sms display for unread sms
		 */
		public RemoteViews displaySMS(Context context) {

			RemoteViews updateViews = createDisplay(context);

			return updateViews;
		}

		

		@Override
		public IBinder onBind(Intent intent) {
			// We don't need to bind to this service
			return null;
		}

		/**
		 * checks, whether or not to display the widget. It will only be
		 * displayed if there are unread SMS.
		 * 
		 * @param context
		 */
		public RemoteViews createDisplay(Context context) {
			// retrieve all unread sms from db.
			// ArrayList<SMSMessage> messages = SMSDao.getAllUnreadMessages();
			
			// retrieve all sms from db.
			ArrayList<SMSMessage> messages = SMSDao.getAllMessages(context);

			int smsCount = messages.size();

			RemoteViews view = new RemoteViews(context.getPackageName(), R.layout.main);
			Log.v(LOG_TAG,"we have "+smsCount+" messages.");
			if (smsCount > 0) {
				// have unread messages, show the widget.
//				Log.i(LOG_TAG, "Showing widget we have unread sms");
				view.setViewVisibility(R.id.MessageWidget, View.VISIBLE);
				// display latest sms

//				Log.d(LOG_TAG, "Current position:"+position);
				if(position > smsCount-1){
					position = smsCount -1;
				}
				if(position < 0){
					position = 0;
				}
				SMSMessage curMessage = messages.get(position);

				ContactInfo curMessageContact = MessageUtils.getContact(context, curMessage.getSenderId(),curMessage.getNumber());

				view.setTextViewText(R.id.Date,curMessage.getFormattedDate(context));
				view.setTextViewText(R.id.Time,curMessage.getFormattedTime(context));
				view.setTextViewText(R.id.MessageContent, curMessage.getBody());
				view.setTextViewText(R.id.ContactName,curMessageContact.getDisplayName());
				view.setTextViewText(R.id.MessageCount, (position+1) + " / " + messages.size());
				
				if(smsCount > position+1) {
					Intent intent = new Intent(context, MessageWidget.class);
					intent.setAction(SHOW_NEXT_SMS_ACTION);
					PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
					view.setOnClickPendingIntent(R.id.NextButton, pi);
					view.setViewVisibility(R.id.NextButton, View.VISIBLE);
				}else{
					view.setViewVisibility(R.id.NextButton, View.INVISIBLE);
				}
				if(0 < position){
					Intent intent = new Intent(context, MessageWidget.class);
					intent.setAction(SHOW_PREVIOUS_SMS_ACTION);
					
					PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
					view.setOnClickPendingIntent(R.id.PrevButton, pi);
					view.setViewVisibility(R.id.PrevButton, View.VISIBLE);
				}else{
					view.setViewVisibility(R.id.PrevButton, View.INVISIBLE);
				}

				Bitmap contactPhoto = curMessageContact.getContactPhoto();
				if (contactPhoto != null) {
					view.setImageViewBitmap(R.id.ContactPic, contactPhoto);
				} else {
					Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.ic_contact_picture);
					int width = 40;
					int height = 40;
					Bitmap resizedbitmap = Bitmap.createScaledBitmap(bmp, width, height, true);

					view.setImageViewBitmap(R.id.ContactPic, bmp);
				}

			} else {
//				Log.i(LOG_TAG, "Hiding widget due to missing sms");
				view.setViewVisibility(R.id.MessageWidget, View.INVISIBLE);
				// Toast.makeText(context, R.string.hidden_message, Toast.LENGTH_SHORT).show();
			}
			return view;
		}
	}
}